<template>
  <el-dialog title="赛福斯特公司党支部党建KPI" :visible="releaseKPIVisible" width="75%" :center="true"
             :close-on-click-modal="false"
             @close="closeDialog">
    <div class="container">
      <el-form size="mini" inline style="display: flex; justify-content: space-between" label-position="right">
        <el-form-item label="支部书记:">
          <el-input v-model="branchSecretary"></el-input>
        </el-form-item>
        <el-form-item label="上传KPI指标任务书:">
          <el-upload style="display: inline-block; margin-right: 10px"
                     :action="uploadAction" :with-credentials="true"
                     :on-success="handleIndicatorTaskBookSuccess"
                     :file-list="fileList" :show-file-list="false">
            <el-button size="mini" type="text" icon="el-icon-paperclip"></el-button>
            <el-tag
                v-if="indicatorTaskBookAttachment.filePath"
                closable size="mini"
                :href="indicatorTaskBookAttachment.filePath"
                target="_blank"
                type="primary" @close="handleDeleteAttachment()">
              {{ indicatorTaskBookAttachment.filePath.split('/').pop() }}
            </el-tag>
          </el-upload>
        </el-form-item>
        <el-form-item>
        </el-form-item>
        <el-form-item>
        </el-form-item>
      </el-form>
      <el-table
          :data="localKpiPartyBuilding"
          border
          :span-method="(params) => objectSpanMethod(params, 'localKpiPartyBuilding')"
          style="width: 100%"
          header-cell-class-name="header-center">
        <el-table-column label="党建KPI">
          <!-- 序号列 -->
          <el-table-column
              label="序号"
              width="55">
            <template slot-scope="scope">
    <span v-if="tableState.localKpiPartyBuilding.indexSerialArr[scope.$index]">
      {{ tableState.localKpiPartyBuilding.indexSerialArr[scope.$index] }}
    </span>
            </template>
          </el-table-column>
          <!-- 第一列 -->
          <el-table-column
              label="一级指标"
              prop="column1" width="260px">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(1, 'localKpiPartyBuilding')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(1, 'localKpiPartyBuilding')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column1" @focus="handleFocus(scope.$index, 'localKpiPartyBuilding')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column1', '_col1Key', $event, 'localKpiPartyBuilding')">
              </el-input>
            </template>
          </el-table-column>
          <!-- 第二列 -->
          <el-table-column
              label="指标要点"
              prop="column2" width="260px">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(2,'localKpiPartyBuilding')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(2,'localKpiPartyBuilding')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column2" @focus="handleFocus(scope.$index,'localKpiPartyBuilding')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column2', '_col2Key', $event,'localKpiPartyBuilding')">
              </el-input>
            </template>
          </el-table-column>

          <!-- 第三列 -->
          <el-table-column
              label="具体内容"
              prop="column3">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(3,'localKpiPartyBuilding')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(3,'localKpiPartyBuilding')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column3" @focus="handleFocus(scope.$index,'localKpiPartyBuilding')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column3', '_col3Key', $event,'localKpiPartyBuilding')">
              </el-input>
            </template>
          </el-table-column>
        </el-table-column>
      </el-table>
      <el-table :data="localKpiPartyPlan" border
                :span-method="(params) => objectSpanMethod(params, 'localKpiPartyPlan')" style="width: 100%"
                header-cell-class-name="header-center">
        <!-- 序号列 -->
        <el-table-column
            label="序号"
            width="60">
          <template slot-scope="scope">
    <span v-if="tableState.localKpiPartyPlan.indexSerialArr[scope.$index]">
      {{ tableState.localKpiPartyPlan.indexSerialArr[scope.$index] }}
    </span>
          </template>
        </el-table-column>
        <el-table-column label="党建工作计划">
          <!-- 第一列 -->
          <el-table-column
              label="一级指标"
              prop="column1" width="260px">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(1, 'localKpiPartyPlan')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(1, 'localKpiPartyPlan')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column1" @focus="handleFocus(scope.$index, 'localKpiPartyPlan')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column1', '_col1Key', $event, 'localKpiPartyPlan')">
              </el-input>
            </template>
          </el-table-column>
          <!-- 第二列 -->
          <el-table-column
              label="指标要点"
              prop="column2" width="260px">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(2, 'localKpiPartyPlan')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(2, 'localKpiPartyPlan')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column2" @focus="handleFocus(scope.$index, 'localKpiPartyPlan')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column2', '_col1Key', $event, 'localKpiPartyPlan')">
              </el-input>
            </template>
          </el-table-column>
          <!-- 第三列 -->
          <el-table-column
              label="基本工作"
              prop="column3">
            <template slot="header" slot-scope="scope">
              <span>{{ scope.column.label }}</span>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-plus"
                  @click="addRow(3,'localKpiPartyPlan')">
              </el-button>
              <el-button
                  size="mini"
                  type="text"
                  icon="el-icon-minus"
                  @click="deleteRow(3,'localKpiPartyPlan')">
              </el-button>
            </template>
            <template slot-scope="scope">
              <el-input
                  v-model="scope.row.column3" @focus="handleFocus(scope.$index,'localKpiPartyPlan')"
                  :style="inputStyle"
                  @input="handleInput(scope.row, 'column3', '_col3Key', $event,'localKpiPartyPlan')">
              </el-input>
            </template>
          </el-table-column>
        </el-table-column>
      </el-table>
      <el-row>
        <el-col><span>模版文件下载:</span>
          <el-link>1.党建kpi表</el-link>&nbsp;&nbsp;&nbsp;&nbsp;<el-link>2.党建工作计划表</el-link>
        </el-col>
      </el-row>

    </div>
    <div slot="footer" class="dialog-footer" style="display: flex; justify-content: center; gap: 10px">
      <el-button type="primary" @click="release" size="mini">发 布</el-button>
      <el-button type="primary" @click="cancle" size="mini">取 消</el-button>
      <el-upload
          :show-file-list="false" action="#"
          accept=".xlsx,.xls"
          :before-upload="handleImportKPIExcel"
      >
        <el-button type="text" icon="el-icon-upload" size="mini">导入党建KPI Excel</el-button>
      </el-upload>
      <el-upload
          :show-file-list="false" action="#"
          accept=".xlsx,.xls"
          :before-upload="handleImportPlanExcel"
          style="margin-left: 16px;"
      >
        <el-button type="text" icon="el-icon-upload" size="mini">导入党建计划 Excel</el-button>
      </el-upload>
    </div>
  </el-dialog>
</template>

<script>
import moment from "moment";
import * as XLSX from 'xlsx'

export default {
  name: "ReleaseKPI",
  props: {
    releaseKPIVisible: Boolean,
    kpiPartyBuilding: Array,
    kpiPartyPlan: Array,
    uploadAction: String,
  },
  data() {
    return {
      localKpiPartyBuilding: [...this.kpiPartyBuilding],
      localKpiPartyPlan: [...this.kpiPartyPlan],
      tableState: {
        localKpiPartyBuilding: {
          currentFocusRowIndex: null,
          spanArr1: [],
          spanArr2: [],
          spanArr3: [],
          indexSerialArr: []
        },
        localKpiPartyPlan: {
          currentFocusRowIndex: null,
          spanArr1: [],
          spanArr2: [],
          spanArr3: [],
          indexSerialArr: []
        }
      },
      rowIdSeed: 1,
      inputStyle: {
        border: 'none',
        background: 'transparent',
        margin: '0',
        padding: '0 5px',
        width: '100%',
        height: '100%',
        'box-sizing': 'border-box'
      },

      indicatorTaskBookAttachment: {},
      branchSecretary: '',
      fileList: []
    }
  },
  methods: {
    getUniqueId() {
      return 'row_' + (this.rowIdSeed++);
    },
    // 获取所有父行
    getAllParentKeys() {
      return [...new Set(this.localKpiPartyBuilding.map(row => row.column1))];
    },
    // 获取某父行下所有子行
    getChildKeys(parentKey) {
      return [...new Set(this.localKpiPartyBuilding.filter(row => row.column1 === parentKey).map(row => row.column2))];
    },
    // 获取某父+子下所有孙行
    getGrandChildRows(parentKey, childKey) {
      return this.localKpiPartyBuilding.filter(row => row.column1 === parentKey && row.column2 === childKey);
    },

    addRow(columnIndex, tableKey) {
      let tableData = this[tableKey];
      let state = this.tableState[tableKey];
      let idx = state.currentFocusRowIndex;
      if (idx == null || idx < 0 || idx >= tableData.length) {
        idx = tableData.length - 1;
      }
      if (columnIndex === 1) {
        const id = this.getUniqueId();
        tableData.push({
          column1: '',
          column2: '',
          column3: '',
          _rowId: id,
          _col1Key: id,
          _col2Key: id + '_c',
          _col3Key: id + '_g'
        });
      } else if (columnIndex === 2) {
        if (tableData.length === 0) {
          this.addRow(1, tableKey);
          return;
        }
        const baseRow = tableData[idx];
        const id = this.getUniqueId();
        tableData.splice(idx + 1, 0, {
          column1: baseRow.column1,
          column2: '',
          column3: '',
          _rowId: id,
          _col1Key: baseRow._col1Key,
          _col2Key: id + '_c',
          _col3Key: id + '_g'
        });
      } else if (columnIndex === 3) {
        if (tableData.length === 0) {
          this.addRow(1, tableKey);
          return;
        }
        const baseRow = tableData[idx];
        const id = this.getUniqueId();
        tableData.splice(idx + 1, 0, {
          column1: baseRow.column1,
          column2: baseRow.column2,
          column3: '',
          _rowId: id,
          _col1Key: baseRow._col1Key,
          _col2Key: baseRow._col2Key,
          _col3Key: id + '_g'
        });
      }
      this.updateSpanArr(tableKey);
    },
    deleteRow(columnIndex, tableKey) {
      let tableData = this[tableKey];
      let state = this.tableState[tableKey];
      if (tableData.length === 0) return;
      let idx = state.currentFocusRowIndex;
      if (idx == null || idx < 0 || idx >= tableData.length) {
        idx = tableData.length - 1;
      }
      const row = tableData[idx];
      if (!row) return;

      if (columnIndex === 1) {
        const allParentKeys = [...new Set(tableData.map(r => r._col1Key))];
        if (allParentKeys.length === 1) return;
        const parentKey = row._col1Key;
        this[tableKey] = tableData.filter(r => r._col1Key !== parentKey);
      } else if (columnIndex === 2) {
        const parentKey = row._col1Key;
        const childKey = row._col2Key;
        const childKeys = [...new Set(tableData.filter(r => r._col1Key === parentKey).map(r => r._col2Key))];
        if (childKeys.length === 1) return;
        this[tableKey] = tableData.filter(r => !(r._col1Key === parentKey && r._col2Key === childKey));
      } else if (columnIndex === 3) {
        const parentKey = row._col1Key;
        const childKey = row._col2Key;
        const grandChildRows = tableData.filter(r => r._col1Key === parentKey && r._col2Key === childKey);
        if (grandChildRows.length === 1) return;
        tableData.splice(idx, 1);
      }
      this.updateSpanArr(tableKey);
      state.currentFocusRowIndex = null;
    },
    updateSpanArr(tableKey) {
      let tableData = this[tableKey];
      let state = this.tableState[tableKey];
      state.spanArr1 = this.getSpanArr(tableData, '_col1Key');
      state.spanArr2 = this.getSpanArr(tableData, '_col2Key');
      state.spanArr3 = this.getSpanArr(tableData, '_col3Key');
      state.indexSerialArr = [];
      let serial = 1;
      for (let i = 0; i < tableData.length; i++) {
        if (state.spanArr2[i] > 0) {
          state.indexSerialArr[i] = serial++;
        } else {
          state.indexSerialArr[i] = '';
        }
      }
    },
    objectSpanMethod({row, column, rowIndex, columnIndex}, tableKey) {
      let state = this.tableState[tableKey];
      if (columnIndex === 0) {
        // 用第三列的合并行数控制序号合并
        return {rowspan: state.spanArr2[rowIndex], colspan: 1};
      }
      const adjustedIndex = columnIndex - 1;
      if (adjustedIndex === 0) {
        return {rowspan: state.spanArr1[rowIndex], colspan: 1};
      } else if (adjustedIndex === 1) {
        return {rowspan: state.spanArr2[rowIndex], colspan: 1};
      } else if (adjustedIndex === 2) {
        return {rowspan: state.spanArr3[rowIndex], colspan: 1};
      }
    },
    handleFocus(rowIndex, tableKey) {
      this.tableState[tableKey].currentFocusRowIndex = rowIndex;
    },
    handleInput(row, prop, keyProp, val, tableKey) {
      row[prop] = val;
      this.updateSpanArr(tableKey);
    },
    tableToTree(tableData) {
      const tree = [];
      const primaryMap = {};
      const pointMap = {};

      tableData.forEach(row => {
        // 用 _col1Key 作为一级id
        if (!primaryMap[row._col1Key]) {
          primaryMap[row._col1Key] = {
            tempId: row._col1Key,
            name: row.column1,
            points: []
          };
          tree.push(primaryMap[row._col1Key]);
        }
        // 用 _col2Key 作为二级id
        if (!pointMap[row._col2Key]) {
          pointMap[row._col2Key] = {
            tempId: row._col2Key,
            name: row.column2,
            details: []
          };
          primaryMap[row._col1Key].points.push(pointMap[row._col2Key]);
        }
        // 用 _col3Key 作为三级id
        pointMap[row._col2Key].details.push({
          tempId: row._col3Key,
          content: row.column3
        });
      });
      return tree;
    },
    release() {
      const treeData = this.tableToTree(this.localKpiPartyBuilding);
      const treeDataPlan = this.tableToTree(this.localKpiPartyPlan);
      const kpiPartyReleaseDTO = {
        title: `${moment().format('YYYY')}年度`,
        year: moment().format('YYYY'),
        branchSecretary: this.branchSecretary,
        indicatorTaskBookAttachment: this.indicatorTaskBookAttachment,
        primaryIndicators: treeData,
        primaryIndicatorPlans: treeDataPlan
      }
      this.$emit('release', kpiPartyReleaseDTO)
      this.$emit('close')
    },
    getSpanArr(data, keyProp) {
      const spanArr = [];
      let pos = 0;
      data.forEach((item, index) => {
        const curVal = item[keyProp];
        const prevVal = index > 0 ? data[index - 1][keyProp] : null;
        if (index === 0) {
          spanArr.push(1);
          pos = 0;
        } else {
          if (curVal === prevVal) {
            spanArr[pos] += 1;
            spanArr.push(0);
          } else {
            spanArr.push(1);
            pos = index;
          }
        }
      });
      return spanArr;
    },
    cancle() {
      this.$emit('close')
    },
    closeDialog() {
      this.$emit('close')
    },
    handleIndicatorTaskBookSuccess(response, file, fileList) {
      this.indicatorTaskBookAttachment = {
        filePath: response.data
      }
    },
    handleDeleteAttachment() {
      this.indicatorTaskBookAttachment = {filePath: ''};
    },
    fillMergedCells(list, key) {
      let lastValue = '';
      for (let i = 0; i < list.length; i++) {
        if (!list[i][key] || list[i][key].toString().trim() === '') {
          list[i][key] = lastValue;
        } else {
          lastValue = list[i][key];
        }
      }
      return list;
    },
    cleanCell(str) {
      if (!str) return '';
      let s = String(str).trim();
      // 去掉开头的数字和点及空格，比如“1. 内容”变成“内容”
      s = s.replace(/^\d+\.?\s*/, '');
      // 去除所有换行
      s = s.replace(/\r?\n/g, '');
      // 去除全角空格
      s = s.replace(/[\u3000]/g, '');
      // 合并多余空格
      s = s.replace(/\s+/g, '');
      return s;
    },
    handleImportKPIExcel(file) {
      return new Promise(async (resolve, reject) => {
        try {
          const data = await this.readExcelFile(file);
          const sheetName = data.SheetNames[0];
          const worksheet = data.Sheets[sheetName];
          const rows = XLSX.utils.sheet_to_json(worksheet, {header: 1, defval: ''});
          const headerRow = rows[1];
          const expectedHeader = ['一级指标', '指标要点', '具体内容'];
          const headerIndexList = expectedHeader.map(h => headerRow.indexOf(h));
          if (headerIndexList.some(idx => idx === -1)) {
            this.$message.error('请使用党建KPI模板导入');
            return false;
          }
          const dataRows = rows.slice(2);
          let list = dataRows
              .filter(row => row.length > 1 && row.some(cell => (cell || '').toString().trim().length > 0))
              .map((row, idx) => ({
                column1: row[headerIndexList[0]],
                column2: row[headerIndexList[1]],
                column3: row[headerIndexList[2]]
              }));

          // === 关键补齐逻辑 ===
          this.fillMergedCells(list, 'column1');
          this.fillMergedCells(list, 'column2');
          // column3一般不需要

          // === 生成key ===
          list = list.map((row, idx) => {
            const col1 = this.cleanCell(row.column1);
            const col2 = this.cleanCell(row.column2);
            const col3 = this.cleanCell(row.column3);
            return {
              ...row,
              _rowId: `row_${idx + 1}`,
              _col1Key: col1,
              _col2Key: col1 + '||' + col2,
              _col3Key: col1 + '||' + col2 + '||' + col3
            };
          });

          this.localKpiPartyBuilding = list;
          this.$nextTick(() => {
            this.updateSpanArr('localKpiPartyBuilding');
          });

          this.$message.success('导入党建KPI成功');
          reject(); // 阻止自动上传
        } catch (e) {
          this.$message.error('导入失败：' + e.message);
          reject(); // 阻止自动上传
        }
      });
    },
    readExcelFile(file) {
      return new Promise((resolve, reject) => {
        const reader = new FileReader();
        reader.onload = e => {
          const data = e.target.result;
          const workbook = XLSX.read(data, {type: 'binary'});
          resolve(workbook);
        };
        reader.onerror = reject;
        reader.readAsBinaryString(file.raw || file);
      });
    },
    handleImportPlanExcel(file) {
      return new Promise(async (resolve, reject) => {
        try {
          const data = await this.readExcelFile(file);
          const sheetName = data.SheetNames[0];
          const worksheet = data.Sheets[sheetName];
          const rows = XLSX.utils.sheet_to_json(worksheet, {header: 1, defval: ''});
          const headerRow = rows[1];
          const expectedHeader = ['一级指标', '指标要点', '基本工作'];
          const headerIndexList = expectedHeader.map(h => headerRow.indexOf(h));
          if (headerIndexList.some(idx => idx === -1)) {
            this.$message.error('请使用党建工作计划模板导入');
            return false;
          }
          const dataRows = rows.slice(2);
          let list = dataRows
              .filter(row => row.length > 1 && row.some(cell => (cell || '').toString().trim().length > 0))
              .map((row, idx) => ({
                column1: row[headerIndexList[0]],
                column2: row[headerIndexList[1]],
                column3: row[headerIndexList[2]]
              }));

          // === 关键补齐逻辑 ===
          this.fillMergedCells(list, 'column1');
          this.fillMergedCells(list, 'column2');
          // column3一般不需要

          // === 生成key ===
          list = list.map((row, idx) => {
            const col1 = this.cleanCell(row.column1);
            const col2 = this.cleanCell(row.column2);
            const col3 = this.cleanCell(row.column3);
            return {
              ...row,
              _rowId: `row_${idx + 1}`,
              _col1Key: col1,
              _col2Key: col1 + '||' + col2,
              _col3Key: col1 + '||' + col2 + '||' + col3
            };
          });

          this.localKpiPartyPlan = list;
          this.$nextTick(() => {
            this.updateSpanArr('localKpiPartyPlan');
          });

          this.$message.success('导入党建工作计划成功');
          reject(); // 阻止自动上传
        } catch (e) {
          this.$message.error('导入失败：' + e.message);
          reject(); // 阻止自动上传
        }
      });
    },
  },
  mounted() {
    this.updateSpanArr('localKpiPartyBuilding');
    this.updateSpanArr('localKpiPartyPlan');
  }
}
</script>

<style scoped>
::v-deep .container {
  padding: 20px;
}

::v-deep .el-table__header-wrapper th {
  white-space: nowrap;
}

::v-deep .el-table__header-wrapper .cell {
  display: flex;
  align-items: center;
}

.el-button {
  margin-left: 15px;
}

/* 表头居中 */
::v-deep .header-center {
  text-align: center !important;
}

/* 隐藏输入框的聚焦效果 */
::v-deep .el-input__inner:focus {
  outline: none;
  box-shadow: none;
}
::v-deep .el-table__cell {
  white-space: normal !important;
  word-break: break-all !important;
}
::v-deep .el-input__inner {
  white-space: normal !important;
  word-break: break-word !important;
  overflow-wrap: break-word !important;
}
</style>